package com.sz.app.oss.api.common.base;

import com.sz.app.oss.constants.MessagesCodes;
import com.sz.app.oss.constants.Permissions;
import com.sz.biz.app.web.BaseController;
import com.sz.biz.common.base.service.AreaManager;
import com.sz.biz.common.base.service.AreaService;
import com.sz.biz.common.base.dto.AreaDto;
import com.sz.biz.common.base.dto.CountryDto;
import com.sz.biz.common.base.dto.CountryModel;
import com.sz.common.base.dto.I18nDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;

import com.sz.common.base.service.I18nBaseService;
import com.sz.common.base.utils.StringUtils;
import io.swagger.annotations.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Function: AreaController <br>
 * Author: penghui.zheng <br>
 * Date: 2016-10-27 10:19:00
 */
@RestController
@RequestMapping("${api}/biz/area")
@Api(description = " ", tags = "029、国家地区管理")
public class AreaController extends BaseController {
    @Autowired
    private AreaService areaService;

    @Autowired
    private AreaManager areaManager;

    @Autowired
    private I18nBaseService i18nService;
    @Value("${i18n.biz.area}")
    private String i18nAreaTable;
    @Value("${i18n.biz.area.cn}")
    private String i18nAreacnTable;
    @Value("${i18n.biz.country}")
    private String i18nCountryTable;

    /**
     * 查询国家
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索国家", notes = "搜索国家")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小,max2000", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序的字段", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "asc", value = "排序方式", dataType = "boolean", paramType = "query", defaultValue = "true")})
    @RequestMapping(value = "/search/country", method = {RequestMethod.GET})
    public ResultDto searchCountry(@RequestParam(required = false) String q,@RequestParam(required = false, defaultValue = "0") int pageIndex,
            @RequestParam(required = false, defaultValue = "10") int pageSize, @RequestParam(required = false) String sort,
            @RequestParam(required = false, defaultValue = "true") Boolean asc) {
        q = StringUtils.replaceSqlPattern(q);
        ResultDto dto = areaService.findCountriesList(new QueryParams(pageSize, pageIndex, q, sort, asc));
        return dto; 
    }

    /**
     * 查询国家（客户）
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索国家（客户）1", notes = "搜索国家（客户）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "customerId", value = "客户id", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "类型（发件地址，或收件地址）", required = false, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/customer/country", method = {RequestMethod.GET})
    public ResultDto searchCountryByCustomerIdAndType(@RequestParam(required = false) String q,
                                               @RequestParam(required = false, defaultValue = "0") int customerId,
                                               @RequestParam(required = false, defaultValue = "0") int type) {
        q = StringUtils.replaceSqlPattern(q);
        List<CountryModel> list = areaService.searchCountryByCustomerIdAndType(q,customerId,type);
        ResultDto dto = new ResultDto();
        dto.setData(list);
        return dto;
    }

    /**
     * 查询城市
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索城市", notes = "搜索城市")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "查询的关键字", required = false, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "countryCode", value = "国家编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小,max2000", required = false, dataType = "int", paramType = "query")
    })
    @RequestMapping(value = "/search/city", method = {RequestMethod.GET})
    public ResultDto searchCity(@RequestParam(required = false) String q, @RequestParam String countryCode, @RequestParam(required = false, defaultValue = "0") int pageIndex,
            @RequestParam(required = false, defaultValue = "10") int pageSize) {
        q = StringUtils.replaceSqlPattern(q);
        ResultDto dto = areaService.searchCity(countryCode, q, pageIndex, pageSize);
        return dto;
    }

    /**
     * 根据父id查询下属地区
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索地区,去重分页(包括国内国外)", notes = "搜索地区,去重不分页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "countryCode", value = "国家编码", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "parentId", value = "父id", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = false, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小,max2000", required = false, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/search", method = {RequestMethod.GET})
    public ResultDto findByParentId(@RequestParam String countryCode, @RequestParam String parentId,
                                    @RequestParam(required = false) String q, @RequestParam(required = false, defaultValue = "0") int pageIndex,
                                    @RequestParam(required = false, defaultValue = "10") int pageSize) {
        q = StringUtils.replaceSqlPattern(q);
        return areaManager.findByParentId(countryCode, parentId, q, pageIndex, pageSize);
    }

    /**
     * 分页查询下属地区
     *
     * @throws ParseException
     * @throws Exception
     */
    @ApiOperation(value = "搜索地区，地区列表", notes = "搜索地区，地区列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "countryCode", value = "国家id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "parentId", value = "父id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小,max2000", required = true, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/searchlist", method = {RequestMethod.GET})
    public ResultDto findAreaListByParentId(@RequestParam(required = false) String countryCode,
                                            @RequestParam(required = false) String parentId, @RequestParam(required = false) String q, @RequestParam int pageIndex,
                                            @RequestParam int pageSize) throws ParseException {
        q = StringUtils.replaceSqlPattern(q);
        ResultDto dto = areaManager.findAreaList(countryCode, parentId, q, pageIndex, pageSize);
        return dto;
    }

    /**
     * 新建一个地区
     *
     * @throws Exception
     */
    @ApiOperation(value = "新建地区", notes = "新建地区<br>权限：" + Permissions.BIZ_MGT_BASE_COUNTRY)
    @ApiImplicitParams({@ApiImplicitParam(name = "areaDto", value = "提交地区信息\r\n "
            + "areaName,areaCode,parentId", required = true, dataType = "AreaDto", paramType = "body")})
    @RequestMapping(value = "", method = {RequestMethod.POST})
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_COUNTRY)

    public ResultDto saveArea(@RequestBody AreaDto areaDto) {
        Integer id = areaManager.saveArea(areaDto);
        i18nService.save(id, areaDto.getI18n(), i18nCountryTable);
        ResultDto result = this.getSaveSuccessDto(MessagesCodes.MODULE_COUNTRY);
        result.setData(id);
        return result;
    }

    /**
     * 根据areaId删除地区 ,逻辑删除
     *
     * @throws Exception
     */
    @ApiOperation(value = "删除一个地区", notes = "非物理删除 打标志 不允许使用<br>权限：" + Permissions.BIZ_MGT_BASE_COUNTRY)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id ", required = true, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "countryCode", value = "countryCode ", required = false, dataType = "string", paramType = "path")})
    @RequestMapping(value = "/{id}", method = {RequestMethod.DELETE})
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_COUNTRY)
    public ResultDto deleteArea(@PathVariable String id, @RequestParam(required = false) String countryCode) {
        areaManager.deleteByAreaId(id, countryCode);
        return getDeleteSuccessDto(MessagesCodes.MODULE_COUNTRY);
    }

    /**
     * 根据areaId删除国家 ,逻辑删除
     *
     * @throws Exception
     */
    @ApiOperation(value = "删除国家", notes = "非物理删除 打标志 不允许使用<br>权限：" + Permissions.BIZ_MGT_BASE_COUNTRY)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "ids", required = true, dataType = "List", paramType = "body")})
    @RequestMapping(value = "/deletions", method = {RequestMethod.POST})
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_COUNTRY)
    public ResultDto deleteCountry(@RequestBody List<Integer> ids) {
        areaManager.deleteByCountryIds(ids);
        return getDeleteSuccessDto(MessagesCodes.MODULE_COUNTRY);
    }

    /**
     * 根据areaId查询国家
     *
     * @throws Exception
     */
    @ApiOperation(value = "查询国家", notes = "查询国家")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "国家的id ", required = true, dataType = "Int", paramType = "path")})
    @RequestMapping(value = "/{id}", method = {RequestMethod.GET})
    public ResultDto getCountryById(@PathVariable int id) {
        CountryDto countryDto = areaManager.findByCountryId(id);
        List<I18nDto> list = i18nService.findI18nDtoByRefId(i18nCountryTable, countryDto.getId());
        countryDto.setI18n(list);
        ResultDto dto = new ResultDto();
        dto.setData(countryDto);
        return dto;
    }

    /**
     * 修改地区
     *
     * @throws Exception
     */
    @ApiOperation(value = "修改地区", notes = "修改地区<br>权限：" + Permissions.BIZ_MGT_BASE_COUNTRY)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "修改地区的areaId ", required = true, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "AreaDto", value = "提交地区信息\r\n "
                    + "areaName,areaCode,parentId", required = true, dataType = "AreaDto", paramType = "body")})
    @RequestMapping(value = "/{id}", method = {RequestMethod.PUT})
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_COUNTRY)
    public ResultDto updateArea(@PathVariable String id, @RequestBody AreaDto areaDto) {
        areaDto.setId(id);
        Integer flag = areaManager.updateArea(areaDto);
        i18nService.save(id, areaDto.getI18n(), i18nCountryTable);
        ResultDto result = this.getUpdateSuccessDto(MessagesCodes.MODULE_COUNTRY);
        result.setData(flag);
        return result;
    }

    /**
     * 分页查询下属地区国际化
     *
     * @throws Exception
     */
    @ApiOperation(value = "分页查询下属地区国际化", notes = "分页查询下属地区国际化")
    @RequestMapping(value = "/i18n/list/{language}", method = {RequestMethod.GET})
    public ResultDto findAreaI18nListByParentId(@PathVariable String language,
                                                @RequestParam(required = false) String q,
                                                @RequestParam(required = true) Boolean unfilled,
                                                @RequestParam(required = false) String countryCode,
                                                @RequestParam(required = false) String parentId, @RequestParam(required = true) int pageIndex,
                                                @RequestParam(required = true) int pageSize, @RequestParam(required = false) String sort,
                                                @RequestParam(required = false, defaultValue = "true") Boolean asc) {
        q = StringUtils.replaceSqlPattern(q);
        Map<String, Object> map = new HashMap<>();
        map.put("unfilled", unfilled);
        ResultDto dto = areaManager.findI18nByParam(new QueryParams(pageSize, pageIndex, q, sort, asc, language).put(map), countryCode, parentId);
        return dto;
    }

    /**
     * 批量新增或修改国际化.
     *
     * @param dtos 要保存或修改的国际化实体集合
     * @return 处理成功与否的返回信息
     */
    @ApiOperation(value = "新增或修改i18n", notes = "批量新增或修改地区国际化<br>权限：" + Permissions.BIZ_MGT_BASE_COUNTRY)
    @RequestMapping(value = "i18n", method = {RequestMethod.POST})
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_COUNTRY)
    public ResultDto saveI18n(@RequestBody @ApiParam(value = "要保存的对象集合", required = true) List<I18nDto> dtos) {
        i18nService.save(dtos, i18nCountryTable);
        areaManager.refreshCountryCache();
        return getSaveI18nSuccessDto();
    }

    /**
     * 分页查询国家
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索国家", notes = "搜索国家")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小,max2000", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "sort", value = "排序的字段", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "asc", value = "排序方式", dataType = "boolean", paramType = "query", defaultValue = "true")})
    @RequestMapping(value = "/search/countrylist", method = {RequestMethod.GET})
    public ResultDto findAreaListByParentId(@RequestParam(required = false) String q, @RequestParam int pageIndex,
                                            @RequestParam int pageSize, @RequestParam(required = false) String sort,
                                            @RequestParam(required = false, defaultValue = "true") Boolean asc) {
        q = StringUtils.replaceSqlPattern(q);
        ResultDto dto = areaManager.findCountryList(new QueryParams(pageSize, pageIndex, q, sort, asc));
        return dto;
    }

    /**
     * 异步校验国家名称
     */
    @ApiOperation(value = "异步校验国家名称", notes = "异步校验国家名称")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "国家名称", required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/checkname", method = {RequestMethod.GET})
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_COUNTRY)
    public ResultDto countryNameCheck(@RequestParam(required = true) String name) {
        areaManager.checkCountryName(name);
        return new ResultDto();
    }

    /**
     * 异步校验国家二字码
     */
    @ApiOperation(value = "异步校验国家二字码", notes = "异步校验国家二字码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "figureCode", value = "国家二字码", required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/checkfigurecode", method = {RequestMethod.GET})
    public ResultDto figureCodeCheck(@RequestParam(required = true) String figureCode) {
        areaManager.checkFigureCode(figureCode);
        return new ResultDto();
    }

    /**
     * 异步校验国家三字码
     */
    @ApiOperation(value = "异步校验国家三字码", notes = "异步校验国家三字码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "triadCode", value = "国家三字码", required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/checktriadcode", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.BIZ_MGT_BASE_AREA)
    public ResultDto triadCodeCheck(@RequestParam(required = true) String triadCode) {
        areaManager.checkTriadCode(triadCode);
        return new ResultDto();
    }

    /**
     * 异步校验国家地区编码
     */
    @ApiOperation(value = "异步校验国家地区编码", notes = "异步校验国家地区编码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "areaCode", value = "国家三字码", required = true, dataType = "string", paramType = "query")})
    @RequestMapping(value = "/checkareacode", method = {RequestMethod.GET})
    //@RequiresPermissions(Permissions.BIZ_MGT_BASE_AREA)
    public ResultDto areaCodeCheck(@RequestParam(required = true) String areaCode) {
        areaManager.checkAreaCode(areaCode);
        return new ResultDto();
    }

    /**
     * 分页查询下属地区
     *
     * @throws Exception
     */
    @ApiOperation(value = "搜索地区，去重分页(只是国外地区)", notes = "搜索地区，去重分页")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "countryCode", value = "国家id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "parentId", value = "父id", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "q", value = "查询的关键字", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "pageIndex", value = "分页", required = true, dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "页面大小,max2000", required = true, dataType = "int", paramType = "query")})
    @RequestMapping(value = "/arealist", method = {RequestMethod.GET})
    public ResultDto findForeignAreaByParentId(@RequestParam(required = false) String countryCode,
                                               @RequestParam(required = false) String parentId,
                                               @RequestParam(required = false) String q,
                                               @RequestParam int pageIndex,
                                               @RequestParam int pageSize) {
        q = StringUtils.replaceSqlPattern(q);
        ResultDto dto = areaService.findAreaByParentId(countryCode, parentId, q, pageIndex, pageSize);
        return dto;
    }
}
